package cn.itzzx.lagou.mybatis.binding;

import cn.itzzx.lagou.mybatis.session.SqlSession;
import cn.itzzx.lagou.mybatis.utils.ClassScanner;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 注册 ｜ 获取Mapper对象的代理
 * @author Martin
 * @since 1.0
 */
public class MapperRegistry {

    private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<>();

    public <T> boolean hasMapper(Class<T> type) {
        return knownMappers.containsKey(type);
    }

    public <T> void addMapper(Class<T> type) {
        //判断当前类是否是接口
        if(type.isInterface()){
            //判断是否重复添加过
            if(hasMapper(type)){
                throw new RuntimeException("Type " + type + " is already known to the MapperRegistry.");
            }
            knownMappers.put(type, new MapperProxyFactory<>(type));
        }
    }

    /**
     * 将 packageName 下的所有接口加载到 knownMappers 中
     * @param packageName
     */
    public void addMappers(String packageName){
        //扫描包的所有接口，类，封装到Set中
        Set<Class<?>> classes = ClassScanner.getClasses(packageName);
        for (Class<?> clazz : classes) {
            addMapper(clazz);
        }
    }

    /**
     * 获取代理工厂实例
     * @param type
     * @param sqlSession
     * @param <T>
     * @return
     */
    public <T> T getMapper(Class<?> type, SqlSession sqlSession) {
        // 前面解析xml做了addMapper操作，这里通过mapper类获取代理工厂
        MapperProxyFactory<?> mapperProxyFactory = knownMappers.get(type);
        return (T) mapperProxyFactory.newInstance(sqlSession);
    }
}
